from pyxmpp2.streamevents import DisconnectedEvent
from pyxmpp2.message import Message 
from pyxmpp2.jid import JID
import logging
from pyxmpp2.interfaces import EventHandler, event_handler, QUIT
from pyxmpp2.streamevents import AuthorizedEvent
from pyxmpp2.client import Client
from pyxmpp2.interfaces import presence_stanza_handler, message_stanza_handler
from xml.etree.ElementTree import tostring
from pyxmpp2.interfaces import XMPPFeatureHandler
from threading import Timer
import time

logging.getLogger().setLevel(logging.INFO)
#配置文件 robot_conf.py
import robot_conf

my_jid=JID( robot_conf.jid )
password=robot_conf.password

from pyxmpp2.settings import XMPPSettings
settings = XMPPSettings({ "password": password,'port':robot_conf.port,'server':robot_conf.server })

import json
client_queue = []
client_life = {}
chk_interval = 3600

def life_check():
    global client_queue , client_life, checker,chk_interval
    for jid in client_queue:
        jid_str = jid.as_string()
        life = 0
        try:
            life = client_life[ jid_str ]
        except:
            pass
        if life>0:
            client_queue.remove( jid )
            client_life.pop( jid_str )
        else:
            client_life[ jid_str ] = life+1
    checker = Timer( chk_interval ,life_check )
    checker.start()
            

def user_reg(stanza):
    global client_queue
    msg = Message(stanza_type = stanza.stanza_type,
                from_jid = stanza.to_jid, to_jid = stanza.from_jid,
                body = json.dumps({'cmd':'ok','key':'reg'}), thread = stanza.thread)
    try:
        client_queue.index( stanza.from_jid )
    except:
        client_queue.append( stanza.from_jid )
    return msg
    
def user_quit(stanza):
    global client_queue
    msg = Message(stanza_type = stanza.stanza_type,
                from_jid = stanza.to_jid, to_jid = stanza.from_jid,
                body = json.dumps({'cmd':'ok','key':'quit'}), thread = stanza.thread)
    try:
        client_queue.remove( stanza.from_jid )
    except:
        pass
    return msg

def user_want(stanza, cmd):
    global client_queue,client
    for jid in client_queue:
        if jid != stanza.from_jid:
            msg = Message(stanza_type = stanza.stanza_type,
               from_jid = stanza.to_jid, to_jid = jid,
               body = json.dumps({'cmd':'rd','key':cmd['key'],'from':stanza.from_jid.as_unicode(),'ident':cmd['ident']}),
               thread = stanza.thread)
            client.send(msg)
            
    return None
    
    
class MyHandler(EventHandler,XMPPFeatureHandler):
    @event_handler()
    def handle_any_event(self, event):
        #logging.info(u"-- {0}".format(event))
        return
        
    @message_stanza_handler()
    def handle_message(self, stanza):
        #logging.info(u"RECV: {0}".format(stanza.from_jid))
        msg = Message( stanza_type = stanza.stanza_type,
                from_jid = stanza.to_jid, to_jid = stanza.from_jid,
                subject = 'Re', body = stanza.body,
                thread = stanza.thread )
        try:
            cmd = json.loads(stanza.body)
            #print('%s %s\nreg %s'%(cmd['cmd'],hash(cmd['cmd']),hash('reg')))
            if cmd['cmd'] == 'reg':
                return user_reg( stanza )
            elif cmd['cmd'] == 'quit':
                return user_quit( stanza )
            elif cmd['cmd'] == 'want':
                return user_want( stanza , cmd )
            else:
                raise Exception
        except Exception as e :
            print('E: %s'%str(e))
            return msg
        
    @event_handler(DisconnectedEvent)
    def handle_disconnected(self, event):
        return QUIT

from _thread import start_new_thread
import time
from xml.etree.ElementTree import tostring
def send_proc( handler1 ):
    message = Message(to_jid = jid_to,body = my_message)
    global client
    for i in range(5):
        c=input('enter...')
        client.send(message)
        #logging.info(u"SEND: {0}".format(tostring(message.get_xml())))
    client.disconnect()
    
h1 = MyHandler()
client = Client(my_jid, [ h1 ], settings)
checker = Timer(chk_interval ,life_check)
checker.start()
client.connect()
try:
    client.run()
except Exception as e:
    checker.cancel()
    client.disconnect()
    logging.info(u"Exception: {0}".format(e))
    

